
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"


#define TXD_PIN (GPIO_NUM_17)
#define RXD_PIN (GPIO_NUM_16)


//LoRa M0
#define LORA_M0_PIN     GPIO_NUM_25
//LoRa M1
#define LORA_M1_PIN     GPIO_NUM_26
//选择初始化Lora引脚宏
#define LORA_GPIO_OUTPUT_PIN_SEL    (1ULL<<GPIO_NUM_25)|(1ULL<<GPIO_NUM_26) //配置GPIO_OUT寄存器
//1ULL = unsigned long long 也就是uin64_t  这里是需要和pin_bit_mask的类型一样~


#define LORA_M0(x)      gpio_set_level(LORA_M0_PIN, x)
#define LORA_M1(x)      gpio_set_level(LORA_M1_PIN, x)
//枚举定义：Lora模式
enum lora_mode
{
    lora_mode_transfer,
    lora_mode_wor,
    lora_mode_conf,
    lora_mode_sleep
};
 


void UART2_Init(void)
{
    const uart_config_t uart_config = {
        .baud_rate = 9600,                      //波特率
        .data_bits = UART_DATA_8_BITS,          //数据位
        .parity = UART_PARITY_DISABLE,          //奇偶校验
        .stop_bits = UART_STOP_BITS_1,          //停止位
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,  //流控制
        .source_clk = UART_SCLK_DEFAULT,        //时钟源
    };
    // We won't use a buffer for sending data.
    uart_driver_install(UART_NUM_2, 2048, 0, 0, NULL, 0);       //安装串口驱动程序：串口2，接收Buff，发送Buff
    uart_param_config(UART_NUM_2, &uart_config);                //配置串口2
    uart_set_pin(UART_NUM_2, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //将UART的信号分配给GPIO引脚

}


void LoRa_GPIO_Init(void)
{
    gpio_config_t io_conf;                  //定义GPIO配置结构体
    io_conf.intr_type = GPIO_INTR_DISABLE;  //禁止中断  
    io_conf.mode = GPIO_MODE_OUTPUT;        //选择输出模式
    io_conf.pin_bit_mask = LORA_GPIO_OUTPUT_PIN_SEL;               //设置GPIO_OUT寄存器
    io_conf.pull_down_en = 0;               //禁止上拉
    io_conf.pull_up_en = 0;                 //禁止下拉
    gpio_config(&io_conf);                  //初始化
}

void LoRa_Rx_Task(void *arg)
{
    uint8_t data;

    while (1)
    {
        uart_read_bytes(UART_NUM_2, &data, 1, portMAX_DELAY);   //接收一个数据
        printf("LoRa_Rx:%x\r\n", data);
    }
    
}

//Lora模块 模式配置函数
void lora_mode_config(enum lora_mode mode)
{
    //vTaskDelay等待滴答，而不是ms，需要正确地转换它。解决方案: vTaskDelay(1000/portTICK_PERIOD_MS)；
    vTaskDelay(100/portTICK_PERIOD_MS);
    switch(mode)
    {
        case lora_mode_transfer : LORA_M0(0); LORA_M1(0); break;
        case lora_mode_wor      : LORA_M0(1); LORA_M1(0); break;
        case lora_mode_conf     : LORA_M0(0); LORA_M1(1); break;
        case lora_mode_sleep    : LORA_M0(1); LORA_M1(1); break;
        default                 : break;
    }
    vTaskDelay(100/portTICK_PERIOD_MS);
}


void App_Lora_Init(void)
{
    UART2_Init();
    LoRa_GPIO_Init();

    //创建接收Lora任务
    xTaskCreate(LoRa_Rx_Task, "LoRa_Rx_Task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL);

    /* 开启配置模式 */
    lora_mode_config(lora_mode_conf);
    
    /* 初始化Lora模块 */
    /* 初始化Lora(地址00 01) (网络地址04)(串口9600,8N1)(信道17)(.....) */
    uint8_t con[10] = {0xC0, 0x00, 0x07, 0x00, 0x01, 0x04, 0x62, 0x00, 0x17, 0x40};
    uart_write_bytes(UART_NUM_2,con, 10);
    /* 开启发送模式 */
    lora_mode_config(lora_mode_transfer);
    printf("已开启发送模式");

     //向另一个Lora模块发送数据 */  //点对点：地址，信道，数据
     uint8_t msgs[10] = {0x00, 0x02, 0x17, 0x01, 0x02, 0x03, 0x04};
     uart_write_bytes(UART_NUM_2, msgs, 7); 
}
